#ifndef DependencyPipe_H
#define DependencyPipe_H
#include"Alphabet.h"
#include"ParserOptions.h"
#include"Parameters.h"
#include"DependencyReader.h"
#include"DependencyWriter.h"

class DependencyPipe{
protected:
	int map_size;
	
	DependencyReader* depReader;
	
	DependencyWriter* depWriter;
	
	bool isCONLL;
	
	void createAlphabet(string* file);
	
	void addLinearFeatures(string &type, vector<string*>* obsVals, int first, int second, string &attachDistance, FeatureVector* fv);
	
	void addCorePosFeatures(string &prefix, string &leftOf1, string* one, string &rightOf1, string &leftOf2, string* two, string &rightOf2, string &attachDistance, FeatureVector* fv);
	
	void addTwoObsFeatures(string &prefix, string* item1F1, string* item1F2, string* item2F1, string* item2F2, string &attachDistance, FeatureVector* fv);
	
	void addDiscourseFeatures(DependencyInstance* instance, int small, int large, int headIndex, int childIndex, string &attDist, FeatureVector* fv);
	
	void addOldMSTStemFeatures(string* hLemma, string* headP, string* cLemma, string* childP, string &attDist, int hL, int cL, FeatureVector* fv);
	
	virtual void addExtendedFeatures(DependencyInstance* instance, FeatureVector* fv);
	
	virtual void writeExtendedFeatures(DependencyInstance* instance, ObjectWriter &out);
	
public:
	ParserOptions* options;

	Alphabet dataAlphabet;
	
	Alphabet typeAlphabet;
	
	vector<string*> types;
	
	vector<int>* typesInt;
	
	bool labeled;
	
	DependencyPipe(ParserOptions* options);
	
	virtual ~DependencyPipe();
	
	void initInputFile(string* file);
	
	void initOutputFile(string* file);
	
	void outputInstance(vector<string*> &forms, vector<string*> &lemma, vector<string*> &cpos, vector<string*> &pos, vector<string*> &labs, vector<int> &heads);
	
	void close();
	
	string* getType(int typeIndex);
	
	vector<int>* createInstances(string* file, string* featFileName);

	vector<int>* createInstances(string *file, vector<DependencyInstance*> *instList);

	void writeInstance(DependencyInstance* instance, ObjectWriter &out);
	
	void closeAlphabets();
	
	DependencyInstance* nextInstance();

	bool add(string* feat, FeatureVector* fv);

	FeatureVector* createFeatureVector(DependencyInstance* instance, bool genFeature);

	void addCoreFeatures(DependencyInstance* instance, int small, int large, bool attR, FeatureVector* fv);

	void addLabeledFeatures(DependencyInstance* instance, int word, string* type, bool attR, bool childFeatures, FeatureVector* fv);
	
	void fillFeatureVectors(DependencyInstance* instance, vector<vector<vector<double> > > &probs,
		vector<vector<vector<vector<double> > > > &nt_probs, Parameters* params);
	
	DependencyInstance* readInstance(ObjectReader &in, int length, vector<vector<vector<double> > > &probs,
		vector<vector<vector<vector<double> > > > &nt_probs, Parameters* params);

	double getScore(double *parameters, int *keys, int size);
};
#endif
